AArch32: Add essential Arch helpers
authorSoby Mathew <[email protected]>
Mon, 9 May 2016 16:49:55 +0000 (17:49 +0100)
committerSoby Mathew <[email protected]>
Wed, 10 Aug 2016 11:34:50 +0000 (12:34 +0100)
This patch adds the essential AArch32 architecture helpers
arch.h and arch_helpers.h and modifies `_types.h` to add AArch32
support.

A new build option `ARCH` is defined in the top level makefile to
enable the component makefiles to choose the right files based on the
Architecture it is being build for. Depending on this flag, either
`AARCH32` or `AARCH64` flag is defined by the Makefile. The default
value of `ARCH` flag is `aarch64`. The AArch32 build support will be
added in a later patch.

Change-Id: I405e5fac02db828a55cd25989b572b64cb005241

Makefile
include/lib/aarch32/arch.h [new file with mode: 0644]
include/lib/aarch32/arch_helpers.h [new file with mode: 0644]
include/lib/stdlib/machine/_types.h

index a68335bdd682e6c9a40210baea6adc866c5ae74f..eb593a7afe9f030abff40214996fb4faf7afd8c5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -45,6 +45,8 @@ include ${MAKE_HELPERS_DIRECTORY}build_env.mk
 # Default values for build configurations
 ################################################################################
 
+# The Target build architecture.
+ARCH                           := aarch64
 # Build verbosity
 V                              := 0
 # Debug build
@@ -468,6 +470,12 @@ else
                 $(eval $(call add_define,PRELOADED_BL33_BASE))
         endif
 endif
+# Define the AARCH32/AARCH64 flag based on the ARCH flag
+ifeq (${ARCH},aarch32)
+        $(eval $(call add_define,AARCH32))
+else
+        $(eval $(call add_define,AARCH64))
+endif
 
 ################################################################################
 # Include BL specific makefiles
diff --git a/include/lib/aarch32/arch.h b/include/lib/aarch32/arch.h
new file mode 100644 (file)
index 0000000..e571ddc
--- /dev/null
@@ -0,0 +1,408 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __ARCH_H__
+#define __ARCH_H__
+
+/*******************************************************************************
+ * MIDR bit definitions
+ ******************************************************************************/
+#define MIDR_IMPL_MASK         0xff
+#define MIDR_IMPL_SHIFT                24
+#define MIDR_VAR_SHIFT         20
+#define MIDR_VAR_BITS          4
+#define MIDR_REV_SHIFT         0
+#define MIDR_REV_BITS          4
+#define MIDR_PN_MASK           0xfff
+#define MIDR_PN_SHIFT          4
+
+/*******************************************************************************
+ * MPIDR macros
+ ******************************************************************************/
+#define MPIDR_CPU_MASK         MPIDR_AFFLVL_MASK
+#define MPIDR_CLUSTER_MASK     (MPIDR_AFFLVL_MASK << MPIDR_AFFINITY_BITS)
+#define MPIDR_AFFINITY_BITS    8
+#define MPIDR_AFFLVL_MASK      0xff
+#define MPIDR_AFFLVL_SHIFT     3
+#define MPIDR_AFF0_SHIFT       0
+#define MPIDR_AFF1_SHIFT       8
+#define MPIDR_AFF2_SHIFT       16
+#define MPIDR_AFFINITY_MASK    0x00ffffff
+#define MPIDR_AFFLVL0          0
+#define MPIDR_AFFLVL1          1
+#define MPIDR_AFFLVL2          2
+
+#define MPIDR_AFFLVL0_VAL(mpidr) \
+               (((mpidr) >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK)
+#define MPIDR_AFFLVL1_VAL(mpidr) \
+               (((mpidr) >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK)
+#define MPIDR_AFFLVL2_VAL(mpidr) \
+               (((mpidr) >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK)
+
+/*
+ * The MPIDR_MAX_AFFLVL count starts from 0. Take care to
+ * add one while using this macro to define array sizes.
+ */
+#define MPIDR_MAX_AFFLVL       2
+
+/* Data Cache set/way op type defines */
+#define DC_OP_ISW                      0x0
+#define DC_OP_CISW                     0x1
+#define DC_OP_CSW                      0x2
+
+/*******************************************************************************
+ * Generic timer memory mapped registers & offsets
+ ******************************************************************************/
+#define CNTCR_OFF                      0x000
+#define CNTFID_OFF                     0x020
+
+#define CNTCR_EN                       (1 << 0)
+#define CNTCR_HDBG                     (1 << 1)
+#define CNTCR_FCREQ(x)                 ((x) << 8)
+
+/*******************************************************************************
+ * System register bit definitions
+ ******************************************************************************/
+/* CLIDR definitions */
+#define LOUIS_SHIFT            21
+#define LOC_SHIFT              24
+#define CLIDR_FIELD_WIDTH      3
+
+/* CSSELR definitions */
+#define LEVEL_SHIFT            1
+
+/* ID_PFR1 definitions */
+#define ID_PFR1_VIRTEXT_SHIFT  12
+#define ID_PFR1_VIRTEXT_MASK   0xf
+#define GET_VIRT_EXT(id)       (((id) >> ID_PFR1_VIRTEXT_SHIFT) \
+                                & ID_PFR1_VIRTEXT_MASK)
+#define ID_PFR1_GIC_SHIFT      28
+#define ID_PFR1_GIC_MASK       0xf
+
+/* SCTLR definitions */
+#define SCTLR_RES1     ((1 << 23) | (1 << 22) | (1 << 11) | (1 << 4) | \
+                       (1 << 3) | SCTLR_CP15BEN_BIT | SCTLR_NTWI_BIT | SCTLR_NTWE_BIT)
+#define SCTLR_M_BIT            (1 << 0)
+#define SCTLR_A_BIT            (1 << 1)
+#define SCTLR_C_BIT            (1 << 2)
+#define SCTLR_CP15BEN_BIT      (1 << 5)
+#define SCTLR_ITD_BIT          (1 << 7)
+#define SCTLR_I_BIT            (1 << 12)
+#define SCTLR_V_BIT            (1 << 13)
+#define SCTLR_NTWI_BIT         (1 << 16)
+#define SCTLR_NTWE_BIT         (1 << 18)
+#define SCTLR_WXN_BIT          (1 << 19)
+#define SCTLR_UWXN_BIT         (1 << 20)
+#define SCTLR_EE_BIT           (1 << 25)
+#define SCTLR_TRE_BIT          (1 << 28)
+#define SCTLR_AFE_BIT          (1 << 29)
+#define SCTLR_TE_BIT           (1 << 30)
+
+/* HSCTLR definitions */
+#define HSCTLR_RES1    ((1 << 29) | (1 << 28) | (1 << 23) | (1 << 22)  \
+                       | (1 << 18) | (1 << 16) | (1 << 11) | (1 << 4)  \
+                       | (1 << 3) | HSCTLR_CP15BEN_BIT)
+#define HSCTLR_M_BIT           (1 << 0)
+#define HSCTLR_A_BIT           (1 << 1)
+#define HSCTLR_C_BIT           (1 << 2)
+#define HSCTLR_CP15BEN_BIT     (1 << 5)
+#define HSCTLR_ITD_BIT         (1 << 7)
+#define HSCTLR_SED_BIT         (1 << 8)
+#define HSCTLR_I_BIT           (1 << 12)
+#define HSCTLR_WXN_BIT         (1 << 19)
+#define HSCTLR_EE_BIT          (1 << 25)
+#define HSCTLR_TE_BIT          (1 << 30)
+
+/* CPACR definitions */
+#define CPACR_FPEN(x)  ((x) << 20)
+#define CPACR_FP_TRAP_PL0      0x1
+#define CPACR_FP_TRAP_ALL      0x2
+#define CPACR_FP_TRAP_NONE     0x3
+
+/* SCR definitions */
+#define SCR_TWE_BIT            (1 << 13)
+#define SCR_TWI_BIT            (1 << 12)
+#define SCR_SIF_BIT            (1 << 9)
+#define SCR_HCE_BIT            (1 << 8)
+#define SCR_SCD_BIT            (1 << 7)
+#define SCR_NET_BIT            (1 << 6)
+#define SCR_AW_BIT             (1 << 5)
+#define SCR_FW_BIT             (1 << 4)
+#define SCR_EA_BIT             (1 << 3)
+#define SCR_FIQ_BIT            (1 << 2)
+#define SCR_IRQ_BIT            (1 << 1)
+#define SCR_NS_BIT             (1 << 0)
+#define SCR_VALID_BIT_MASK     0x33ff
+
+#define GET_NS_BIT(scr)                ((scr) & SCR_NS_BIT)
+
+/* HCR definitions */
+#define HCR_AMO_BIT            (1 << 5)
+#define HCR_IMO_BIT            (1 << 4)
+#define HCR_FMO_BIT            (1 << 3)
+
+/* CNTHCTL definitions */
+#define EVNTEN_BIT             (1 << 2)
+#define PL1PCEN_BIT            (1 << 1)
+#define PL1PCTEN_BIT           (1 << 0)
+
+/* CNTKCTL definitions */
+#define PL0PTEN_BIT            (1 << 9)
+#define PL0VTEN_BIT            (1 << 8)
+#define PL0PCTEN_BIT           (1 << 0)
+#define PL0VCTEN_BIT           (1 << 1)
+#define EVNTEN_BIT             (1 << 2)
+#define EVNTDIR_BIT            (1 << 3)
+#define EVNTI_SHIFT            4
+#define EVNTI_MASK             0xf
+
+/* HCPTR definitions */
+#define TCPAC_BIT              (1 << 31)
+#define TTA_BIT                        (1 << 20)
+#define TCP11_BIT              (1 << 10)
+#define TCP10_BIT              (1 << 10)
+
+/* NASCR definitions */
+#define NSASEDIS_BIT           (1 << 15)
+#define NASCR_CP11_BIT         (1 << 11)
+#define NASCR_CP10_BIT         (1 << 10)
+
+/* CPACR definitions */
+#define ASEDIS_BIT             (1 << 31)
+#define TRCDIS_BIT             (1 << 28)
+#define CPACR_CP11_SHIFT       22
+#define CPACR_CP10_SHIFT       20
+#define CPACR_ENABLE_FP_ACCESS (0x3 << CPACR_CP11_SHIFT |\
+                                       0x3 << CPACR_CP10_SHIFT)
+
+/* FPEXC definitions */
+#define FPEXC_EN_BIT           (1 << 30)
+
+/* SPSR/CPSR definitions */
+#define SPSR_FIQ_BIT           (1 << 0)
+#define SPSR_IRQ_BIT           (1 << 1)
+#define SPSR_ABT_BIT           (1 << 2)
+#define SPSR_AIF_SHIFT         6
+#define SPSR_AIF_MASK          0x7
+
+#define SPSR_E_SHIFT           9
+#define SPSR_E_MASK            0x1
+#define SPSR_E_LITTLE          0
+#define SPSR_E_BIG             1
+
+#define SPSR_T_SHIFT           5
+#define SPSR_T_MASK            0x1
+#define SPSR_T_ARM             0
+#define SPSR_T_THUMB           1
+
+#define SPSR_MODE_SHIFT                0
+#define SPSR_MODE_MASK         0x7
+
+
+#define DISABLE_ALL_EXCEPTIONS \
+               (SPSR_FIQ_BIT | SPSR_IRQ_BIT | SPSR_ABT_BIT)
+
+/*
+ * TTBCR definitions
+ */
+/* The ARM Trusted Firmware uses the long descriptor format */
+#define TTBCR_EAE_BIT          (1 << 31)
+
+#define TTBCR_SH1_NON_SHAREABLE                (0x0 << 28)
+#define TTBCR_SH1_OUTER_SHAREABLE      (0x2 << 28)
+#define TTBCR_SH1_INNER_SHAREABLE      (0x3 << 28)
+
+#define TTBCR_RGN1_OUTER_NC    (0x0 << 26)
+#define TTBCR_RGN1_OUTER_WBA   (0x1 << 26)
+#define TTBCR_RGN1_OUTER_WT    (0x2 << 26)
+#define TTBCR_RGN1_OUTER_WBNA  (0x3 << 26)
+
+#define TTBCR_RGN1_INNER_NC    (0x0 << 24)
+#define TTBCR_RGN1_INNER_WBA   (0x1 << 24)
+#define TTBCR_RGN1_INNER_WT    (0x2 << 24)
+#define TTBCR_RGN1_INNER_WBNA  (0x3 << 24)
+
+#define TTBCR_EPD1_BIT         (1 << 23)
+#define TTBCR_A1_BIT           (1 << 22)
+
+#define TTBCR_T1SZ_SHIFT       16
+#define TTBCR_T1SZ_MASK                (0x7)
+
+#define TTBCR_SH0_NON_SHAREABLE                (0x0 << 12)
+#define TTBCR_SH0_OUTER_SHAREABLE      (0x2 << 12)
+#define TTBCR_SH0_INNER_SHAREABLE      (0x3 << 12)
+
+#define TTBCR_RGN0_OUTER_NC    (0x0 << 10)
+#define TTBCR_RGN0_OUTER_WBA   (0x1 << 10)
+#define TTBCR_RGN0_OUTER_WT    (0x2 << 10)
+#define TTBCR_RGN0_OUTER_WBNA  (0x3 << 10)
+
+#define TTBCR_RGN0_INNER_NC    (0x0 << 8)
+#define TTBCR_RGN0_INNER_WBA   (0x1 << 8)
+#define TTBCR_RGN0_INNER_WT    (0x2 << 8)
+#define TTBCR_RGN0_INNER_WBNA  (0x3 << 8)
+
+#define TTBCR_EPD0_BIT         (1 << 7)
+#define TTBCR_T0SZ_SHIFT       0
+#define TTBCR_T0SZ_MASK                (0x7)
+
+#define MODE_RW_SHIFT          0x4
+#define MODE_RW_MASK           0x1
+#define MODE_RW_32             0x1
+
+#define MODE32_SHIFT           0
+#define MODE32_MASK            0x1f
+#define MODE32_usr             0x10
+#define MODE32_fiq             0x11
+#define MODE32_irq             0x12
+#define MODE32_svc             0x13
+#define MODE32_mon             0x16
+#define MODE32_abt             0x17
+#define MODE32_hyp             0x1a
+#define MODE32_und             0x1b
+#define MODE32_sys             0x1f
+
+#define GET_M32(mode)          (((mode) >> MODE32_SHIFT) & MODE32_MASK)
+
+#define SPSR_MODE32(mode, isa, endian, aif)            \
+       (MODE_RW_32 << MODE_RW_SHIFT |                  \
+       ((mode) & MODE32_MASK) << MODE32_SHIFT |        \
+       ((isa) & SPSR_T_MASK) << SPSR_T_SHIFT |         \
+       ((endian) & SPSR_E_MASK) << SPSR_E_SHIFT |      \
+       ((aif) & SPSR_AIF_MASK) << SPSR_AIF_SHIFT)
+
+/*
+ * CTR definitions
+ */
+#define CTR_CWG_SHIFT          24
+#define CTR_CWG_MASK           0xf
+#define CTR_ERG_SHIFT          20
+#define CTR_ERG_MASK           0xf
+#define CTR_DMINLINE_SHIFT     16
+#define CTR_DMINLINE_WIDTH     4
+#define CTR_DMINLINE_MASK      ((1 << 4) - 1)
+#define CTR_L1IP_SHIFT         14
+#define CTR_L1IP_MASK          0x3
+#define CTR_IMINLINE_SHIFT     0
+#define CTR_IMINLINE_MASK      0xf
+
+#define MAX_CACHE_LINE_SIZE    0x800 /* 2KB */
+
+/*******************************************************************************
+ * Definitions of register offsets and fields in the CNTCTLBase Frame of the
+ * system level implementation of the Generic Timer.
+ ******************************************************************************/
+#define CNTNSAR                        0x4
+#define CNTNSAR_NS_SHIFT(x)    (x)
+
+#define CNTACR_BASE(x)         (0x40 + ((x) << 2))
+#define CNTACR_RPCT_SHIFT      0x0
+#define CNTACR_RVCT_SHIFT      0x1
+#define CNTACR_RFRQ_SHIFT      0x2
+#define CNTACR_RVOFF_SHIFT     0x3
+#define CNTACR_RWVT_SHIFT      0x4
+#define CNTACR_RWPT_SHIFT      0x5
+
+/* MAIR macros */
+#define MAIR0_ATTR_SET(attr, index)    ((attr) << ((index) << 3))
+#define MAIR1_ATTR_SET(attr, index)    ((attr) << (((index) - 3) << 3))
+
+/* System register defines The format is: coproc, opt1, CRn, CRm, opt2 */
+#define SCR            p15, 0, c1, c1, 0
+#define SCTLR          p15, 0, c1, c0, 0
+#define MPIDR          p15, 0, c0, c0, 5
+#define MIDR           p15, 0, c0, c0, 0
+#define VBAR           p15, 0, c12, c0, 0
+#define MVBAR          p15, 0, c12, c0, 1
+#define NSACR          p15, 0, c1, c1, 2
+#define CPACR          p15, 0, c1, c0, 2
+#define DCCIMVAC       p15, 0, c7, c14, 1
+#define DCCMVAC                p15, 0, c7, c10, 1
+#define DCIMVAC                p15, 0, c7, c6, 1
+#define DCCISW         p15, 0, c7, c14, 2
+#define DCCSW          p15, 0, c7, c10, 2
+#define DCISW          p15, 0, c7, c6, 2
+#define CTR            p15, 0, c0, c0, 1
+#define CNTFRQ         p15, 0, c14, c0, 0
+#define ID_PFR1                p15, 0, c0, c1, 1
+#define MAIR0          p15, 0, c10, c2, 0
+#define MAIR1          p15, 0, c10, c2, 1
+#define TTBCR          p15, 0, c2, c0, 2
+#define TTBR0          p15, 0, c2, c0, 0
+#define TTBR1          p15, 0, c2, c0, 1
+#define TLBIALL                p15, 0, c8, c7, 0
+#define TLBIALLIS      p15, 0, c8, c3, 0
+#define TLBIMVA                p15, 0, c8, c7, 1
+#define TLBIMVAA       p15, 0, c8, c7, 3
+#define HSCTLR         p15, 4, c1, c0, 0
+#define HCR            p15, 4, c1, c1, 0
+#define HCPTR          p15, 4, c1, c1, 2
+#define CNTHCTL                p15, 4, c14, c1, 0
+#define VPIDR          p15, 4, c0, c0, 0
+#define VMPIDR         p15, 4, c0, c0, 5
+#define ISR            p15, 0, c12, c1, 0
+#define CLIDR          p15, 1, c0, c0, 1
+#define CSSELR         p15, 2, c0, c0, 0
+#define CCSIDR         p15, 1, c0, c0, 0
+
+/* GICv3 CPU Interface system register defines. The format is: coproc, opt1, CRn, CRm, opt2 */
+#define ICC_IAR1       p15, 0, c12, c12, 0
+#define ICC_IAR0       p15, 0, c12, c8, 0
+#define ICC_EOIR1      p15, 0, c12, c12, 1
+#define ICC_EOIR0      p15, 0, c12, c8, 1
+#define ICC_HPPIR1     p15, 0, c12, c12, 2
+#define ICC_HPPIR0     p15, 0, c12, c8, 2
+#define ICC_BPR1       p15, 0, c12, c12, 3
+#define ICC_BPR0       p15, 0, c12, c8, 3
+#define ICC_DIR                p15, 0, c12, c11, 1
+#define ICC_PMR                p15, 0, c4, c6, 0
+#define ICC_RPR                p15, 0, c12, c11, 3
+#define ICC_CTLR       p15, 0, c12, c12, 4
+#define ICC_MCTLR      p15, 6, c12, c12, 4
+#define ICC_SRE                p15, 0, c12, c12, 5
+#define ICC_HSRE       p15, 4, c12, c9, 5
+#define ICC_MSRE       p15, 6, c12, c12, 5
+#define ICC_IGRPEN0    p15, 0, c12, c12, 6
+#define ICC_IGRPEN1    p15, 0, c12, c12, 7
+#define ICC_MGRPEN1    p15, 6, c12, c12, 7
+
+/* 64 bit system register defines The format is: coproc, opt1, CRm */
+#define TTBR0_64       p15, 0, c2
+#define TTBR1_64       p15, 1, c2
+#define CNTVOFF_64     p15, 4, c14
+#define VTTBR_64       p15, 6, c2
+#define CNTPCT_64      p15, 0, c14
+
+/* 64 bit GICv3 CPU Interface system register defines. The format is: coproc, opt1, CRm */
+#define ICC_SGI1R_EL1_64       p15, 0, c12
+#define ICC_ASGI1R_EL1_64      p15, 1, c12
+#define ICC_SGI0R_EL1_64       p15, 2, c12
+
+#endif /* __ARCH_H__ */
diff --git a/include/lib/aarch32/arch_helpers.h b/include/lib/aarch32/arch_helpers.h
new file mode 100644 (file)
index 0000000..ddf660b
--- /dev/null
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __ARCH_HELPERS_H__
+#define __ARCH_HELPERS_H__
+
+#include <arch.h>      /* for additional register definitions */
+#include <stdint.h>
+#include <types.h>
+
+/**********************************************************************
+ * Macros which create inline functions to read or write CPU system
+ * registers
+ *********************************************************************/
+
+#define _DEFINE_COPROCR_WRITE_FUNC(_name, coproc, opc1, CRn, CRm, opc2)        \
+static inline void write_## _name(u_register_t v)                      \
+{                                                                      \
+       __asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
+}
+
+#define _DEFINE_COPROCR_READ_FUNC(_name, coproc, opc1, CRn, CRm, opc2) \
+static inline u_register_t read_ ## _name(void)                                \
+{                                                                      \
+       u_register_t v;                                                 \
+       __asm__ volatile ("mrc "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : "=r" (v));\
+       return v;                                                       \
+}
+
+/*
+ *  The undocumented %Q and %R extended asm are used to implemented the below
+ *  64 bit `mrrc` and `mcrr` instructions. It works only on Little Endian
+ *  systems for GCC versions < 4.6. Above GCC 4.6, both Little Endian and
+ *  Big Endian systems generate the right instruction encoding.
+ */
+#if !(__GNUC__ > (4) || __GNUC__ == (4) && __GNUC_MINOR__ >= (6))
+#error "GCC 4.6 or above is required to build AArch32 Trusted Firmware"
+#endif
+
+#define _DEFINE_COPROCR_WRITE_FUNC_64(_name, coproc, opc1, CRm)                \
+static inline void write64_## _name(uint64_t v)                                \
+{                                                                      \
+       __asm__ volatile ("mcrr "#coproc","#opc1", %Q0, %R0,"#CRm : : "r" (v));\
+}
+
+#define _DEFINE_COPROCR_READ_FUNC_64(_name, coproc, opc1, CRm)         \
+static inline uint64_t read64_## _name(void)                           \
+{      uint64_t v;                                                     \
+       __asm__ volatile ("mrrc "#coproc","#opc1", %Q0, %R0,"#CRm : "=r" (v));\
+       return v;                                                       \
+}
+
+#define _DEFINE_SYSREG_READ_FUNC(_name, _reg_name)                     \
+static inline u_register_t read_ ## _name(void)                                \
+{                                                                      \
+       u_register_t v;                                                 \
+       __asm__ volatile ("mrs %0, " #_reg_name : "=r" (v));            \
+       return v;                                                       \
+}
+
+#define _DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name)                    \
+static inline void write_ ## _name(u_register_t v)                     \
+{                                                                      \
+       __asm__ volatile ("msr " #_reg_name ", %0" : : "r" (v));        \
+}
+
+#define _DEFINE_SYSREG_WRITE_CONST_FUNC(_name, _reg_name)              \
+static inline void write_ ## _name(const u_register_t v)               \
+{                                                                      \
+       __asm__ volatile ("msr " #_reg_name ", %0" : : "i" (v));        \
+}
+
+/* Define read function for coproc register */
+#define DEFINE_COPROCR_READ_FUNC(_name, ...)                           \
+       _DEFINE_COPROCR_READ_FUNC(_name, __VA_ARGS__)
+
+/* Define read & write function for coproc register */
+#define DEFINE_COPROCR_RW_FUNCS(_name, ...)                            \
+       _DEFINE_COPROCR_READ_FUNC(_name, __VA_ARGS__)                   \
+       _DEFINE_COPROCR_WRITE_FUNC(_name, __VA_ARGS__)
+
+/* Define 64 bit read function for coproc register */
+#define DEFINE_COPROCR_READ_FUNC_64(_name, ...)                        \
+       _DEFINE_COPROCR_READ_FUNC_64(_name, __VA_ARGS__)
+
+/* Define 64 bit read & write function for coproc register */
+#define DEFINE_COPROCR_RW_FUNCS_64(_name, ...)                                 \
+       _DEFINE_COPROCR_READ_FUNC_64(_name, __VA_ARGS__)                \
+       _DEFINE_COPROCR_WRITE_FUNC_64(_name, __VA_ARGS__)
+
+/* Define read & write function for system register */
+#define DEFINE_SYSREG_RW_FUNCS(_name)                                  \
+       _DEFINE_SYSREG_READ_FUNC(_name, _name)                          \
+       _DEFINE_SYSREG_WRITE_FUNC(_name, _name)
+
+/**********************************************************************
+ * Macros to create inline functions for tlbi operations
+ *********************************************************************/
+
+#define _DEFINE_TLBIOP_FUNC(_op, coproc, opc1, CRn, CRm, opc2)         \
+static inline void tlbi##_op(void)                                     \
+{                                                                      \
+       u_register_t v = 0;                                             \
+       __asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
+}
+
+#define _DEFINE_TLBIOP_PARAM_FUNC(_op, coproc, opc1, CRn, CRm, opc2)   \
+static inline void tlbi##_op(u_register_t v)                           \
+{                                                                      \
+       __asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
+}
+
+/* Define function for simple TLBI operation */
+#define DEFINE_TLBIOP_FUNC(_op, ...)                                   \
+       _DEFINE_TLBIOP_FUNC(_op, __VA_ARGS__)
+
+/* Define function for TLBI operation with register parameter */
+#define DEFINE_TLBIOP_PARAM_FUNC(_op, ...)                             \
+       _DEFINE_TLBIOP_PARAM_FUNC(_op, __VA_ARGS__)
+
+/**********************************************************************
+ * Macros to create inline functions for DC operations
+ *********************************************************************/
+#define _DEFINE_DCOP_PARAM_FUNC(_op, coproc, opc1, CRn, CRm, opc2)     \
+static inline void dc##_op(u_register_t v)                             \
+{                                                                      \
+       __asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
+}
+
+/* Define function for DC operation with register parameter */
+#define DEFINE_DCOP_PARAM_FUNC(_op, ...)                               \
+       _DEFINE_DCOP_PARAM_FUNC(_op, __VA_ARGS__)
+
+/**********************************************************************
+ * Macros to create inline functions for system instructions
+ *********************************************************************/
+ /* Define function for simple system instruction */
+#define DEFINE_SYSOP_FUNC(_op)                                         \
+static inline void _op(void)                                           \
+{                                                                      \
+       __asm__ (#_op);                                                 \
+}
+
+
+/* Define function for system instruction with type specifier */
+#define DEFINE_SYSOP_TYPE_FUNC(_op, _type)                             \
+static inline void _op ## _type(void)                                  \
+{                                                                      \
+       __asm__ (#_op " " #_type);                                      \
+}
+
+/* Define function for system instruction with register parameter */
+#define DEFINE_SYSOP_TYPE_PARAM_FUNC(_op, _type)                       \
+static inline void _op ## _type(u_register_t v)                                \
+{                                                                      \
+        __asm__ (#_op " " #_type ", %0" : : "r" (v));                  \
+}
+
+void flush_dcache_range(uintptr_t addr, size_t size);
+void clean_dcache_range(uintptr_t addr, size_t size);
+void inv_dcache_range(uintptr_t addr, size_t size);
+
+DEFINE_SYSOP_FUNC(wfi)
+DEFINE_SYSOP_FUNC(wfe)
+DEFINE_SYSOP_FUNC(sev)
+DEFINE_SYSOP_TYPE_FUNC(dsb, sy)
+DEFINE_SYSOP_TYPE_FUNC(dmb, sy)
+DEFINE_SYSOP_TYPE_FUNC(dsb, ish)
+DEFINE_SYSOP_TYPE_FUNC(dmb, ish)
+DEFINE_SYSOP_FUNC(isb)
+
+DEFINE_SYSREG_RW_FUNCS(spsr)
+DEFINE_SYSREG_RW_FUNCS(cpsr)
+
+/*******************************************************************************
+ * System register accessor prototypes
+ ******************************************************************************/
+DEFINE_COPROCR_READ_FUNC(mpidr, MPIDR)
+DEFINE_COPROCR_READ_FUNC(midr, MIDR)
+DEFINE_COPROCR_READ_FUNC(id_pfr1, ID_PFR1)
+DEFINE_COPROCR_READ_FUNC(isr, ISR)
+DEFINE_COPROCR_READ_FUNC(clidr, CLIDR)
+DEFINE_COPROCR_READ_FUNC_64(cntpct, CNTPCT_64)
+
+DEFINE_COPROCR_RW_FUNCS(scr, SCR)
+DEFINE_COPROCR_RW_FUNCS(ctr, CTR)
+DEFINE_COPROCR_RW_FUNCS(sctlr, SCTLR)
+DEFINE_COPROCR_RW_FUNCS(hsctlr, HSCTLR)
+DEFINE_COPROCR_RW_FUNCS(hcr, HCR)
+DEFINE_COPROCR_RW_FUNCS(hcptr, HCPTR)
+DEFINE_COPROCR_RW_FUNCS(cntfrq, CNTFRQ)
+DEFINE_COPROCR_RW_FUNCS(cnthctl, CNTHCTL)
+DEFINE_COPROCR_RW_FUNCS(mair0, MAIR0)
+DEFINE_COPROCR_RW_FUNCS(mair1, MAIR1)
+DEFINE_COPROCR_RW_FUNCS(ttbcr, TTBCR)
+DEFINE_COPROCR_RW_FUNCS(ttbr0, TTBR0)
+DEFINE_COPROCR_RW_FUNCS_64(ttbr0, TTBR0_64)
+DEFINE_COPROCR_RW_FUNCS(ttbr1, TTBR1)
+DEFINE_COPROCR_RW_FUNCS(vpidr, VPIDR)
+DEFINE_COPROCR_RW_FUNCS(vmpidr, VMPIDR)
+DEFINE_COPROCR_RW_FUNCS_64(vttbr, VTTBR_64)
+DEFINE_COPROCR_RW_FUNCS_64(ttbr1, TTBR1_64)
+DEFINE_COPROCR_RW_FUNCS_64(cntvoff, CNTVOFF_64)
+DEFINE_COPROCR_RW_FUNCS(csselr, CSSELR)
+
+DEFINE_COPROCR_RW_FUNCS(icc_sre_el1, ICC_SRE)
+DEFINE_COPROCR_RW_FUNCS(icc_sre_el2, ICC_HSRE)
+DEFINE_COPROCR_RW_FUNCS(icc_sre_el3, ICC_MSRE)
+DEFINE_COPROCR_RW_FUNCS(icc_pmr_el1, ICC_PMR)
+DEFINE_COPROCR_RW_FUNCS(icc_igrpen1_el3, ICC_MGRPEN1)
+DEFINE_COPROCR_RW_FUNCS(icc_igrpen0_el1, ICC_IGRPEN0)
+DEFINE_COPROCR_RW_FUNCS(icc_hppir0_el1, ICC_HPPIR0)
+DEFINE_COPROCR_RW_FUNCS(icc_hppir1_el1, ICC_HPPIR1)
+DEFINE_COPROCR_RW_FUNCS(icc_iar0_el1, ICC_IAR0)
+DEFINE_COPROCR_RW_FUNCS(icc_iar1_el1, ICC_IAR1)
+DEFINE_COPROCR_RW_FUNCS(icc_eoir0_el1, ICC_EOIR0)
+DEFINE_COPROCR_RW_FUNCS(icc_eoir1_el1, ICC_EOIR1)
+
+/*
+ * TLBI operation prototypes
+ */
+DEFINE_TLBIOP_FUNC(all, TLBIALL)
+DEFINE_TLBIOP_FUNC(allis, TLBIALLIS)
+DEFINE_TLBIOP_PARAM_FUNC(mva, TLBIMVA)
+DEFINE_TLBIOP_PARAM_FUNC(mvaa, TLBIMVAA)
+
+/*
+ * DC operation prototypes
+ */
+DEFINE_DCOP_PARAM_FUNC(civac, DCCIMVAC)
+DEFINE_DCOP_PARAM_FUNC(ivac, DCIMVAC)
+DEFINE_DCOP_PARAM_FUNC(cvac, DCCMVAC)
+
+/* Previously defined accessor functions with incomplete register names  */
+#define dsb()                  dsbsy()
+
+#define IS_IN_SECURE() \
+       (GET_NS_BIT(read_scr()) == 0)
+
+ /*
+  * If EL3 is AArch32, then secure PL1 and monitor mode correspond to EL3
+  */
+#define IS_IN_EL3() \
+       ((GET_M32(read_cpsr()) == MODE32_mon) ||        \
+               (IS_IN_SECURE() && (GET_M32(read_cpsr()) != MODE32_usr)))
+
+/* Macros for compatibility with AArch64 system registers */
+#define read_mpidr_el1()       read_mpidr()
+
+#define read_scr_el3()         read_scr()
+#define write_scr_el3(_v)      write_scr(_v)
+
+#define read_hcr_el2()         read_hcr()
+#define write_hcr_el2(_v)      write_hcr(_v)
+
+#define read_cpacr_el1()       read_cpacr()
+#define write_cpacr_el1(_v)    write_cpacr(_v)
+
+#define read_cntfrq_el0()      read_cntfrq()
+#define write_cntfrq_el0(_v)   write_cntfrq(_v)
+#define read_isr_el1()         read_isr()
+
+#define read_cntpct_el0()      read64_cntpct()
+
+#endif /* __ARCH_HELPERS_H__ */
index 7e993c4c370a92855c5ec7ed8a4a8bc38db3b1f3..fb1083b74f49f9ec51ae07fc84b7013053ccf025 100644 (file)
  *     From: @(#)types.h       8.3 (Berkeley) 1/5/94
  * $FreeBSD$
  */
+/*
+ * Portions copyright (c) 2016, ARM Limited and Contributors.
+ * All rights reserved.
+ */
 
 #ifndef _MACHINE__TYPES_H_
 #define        _MACHINE__TYPES_H_
@@ -48,19 +52,56 @@ typedef     short                   __int16_t;
 typedef        unsigned short          __uint16_t;
 typedef        int                     __int32_t;
 typedef        unsigned int            __uint32_t;
+
+
+/*
+ * Standard type definitions which are different in AArch64 and AArch32
+ */
+#ifdef AARCH32
+typedef        long long               __int64_t;
+typedef        unsigned long long      __uint64_t;
+typedef        __int32_t       __critical_t;
+typedef        __int32_t       __intfptr_t;
+typedef        __int32_t       __intptr_t;
+typedef        __int32_t       __ptrdiff_t;            /* ptr1 - ptr2 */
+typedef        __int32_t       __register_t;
+typedef        __int32_t       __segsz_t;              /* segment size (in pages) */
+typedef        __uint32_t      __size_t;               /* sizeof() */
+typedef        __int32_t       __ssize_t;              /* byte count or error */
+typedef        __uint32_t      __uintfptr_t;
+typedef        __uint32_t      __uintptr_t;
+typedef        __uint32_t      __u_register_t;
+typedef        __uint32_t      __vm_offset_t;
+typedef        __uint32_t      __vm_paddr_t;
+typedef        __uint32_t      __vm_size_t;
+#elif defined AARCH64
 typedef        long                    __int64_t;
 typedef        unsigned long           __uint64_t;
+typedef        __int64_t       __critical_t;
+typedef        __int64_t       __intfptr_t;
+typedef        __int64_t       __intptr_t;
+typedef        __int64_t       __ptrdiff_t;            /* ptr1 - ptr2 */
+typedef        __int64_t       __register_t;
+typedef        __int64_t       __segsz_t;              /* segment size (in pages) */
+typedef        __uint64_t      __size_t;               /* sizeof() */
+typedef        __int64_t       __ssize_t;              /* byte count or error */
+typedef        __uint64_t      __uintfptr_t;
+typedef        __uint64_t      __uintptr_t;
+typedef        __uint64_t      __u_register_t;
+typedef        __uint64_t      __vm_offset_t;
+typedef        __uint64_t      __vm_paddr_t;
+typedef        __uint64_t      __vm_size_t;
+#else
+#error "Only AArch32 or AArch64 supported"
+#endif /* AARCH32 */
 
 /*
  * Standard type definitions.
  */
 typedef        __int32_t       __clock_t;              /* clock()... */
-typedef        __int64_t       __critical_t;
 typedef        double          __double_t;
 typedef        float           __float_t;
-typedef        __int64_t       __intfptr_t;
 typedef        __int64_t       __intmax_t;
-typedef        __int64_t       __intptr_t;
 typedef        __int32_t       __int_fast8_t;
 typedef        __int32_t       __int_fast16_t;
 typedef        __int32_t       __int_fast32_t;
@@ -69,15 +110,8 @@ typedef     __int8_t        __int_least8_t;
 typedef        __int16_t       __int_least16_t;
 typedef        __int32_t       __int_least32_t;
 typedef        __int64_t       __int_least64_t;
-typedef        __int64_t       __ptrdiff_t;            /* ptr1 - ptr2 */
-typedef        __int64_t       __register_t;
-typedef        __int64_t       __segsz_t;              /* segment size (in pages) */
-typedef        __uint64_t      __size_t;               /* sizeof() */
-typedef        __int64_t       __ssize_t;              /* byte count or error */
 typedef        __int64_t       __time_t;               /* time()... */
-typedef        __uint64_t      __uintfptr_t;
 typedef        __uint64_t      __uintmax_t;
-typedef        __uint64_t      __uintptr_t;
 typedef        __uint32_t      __uint_fast8_t;
 typedef        __uint32_t      __uint_fast16_t;
 typedef        __uint32_t      __uint_fast32_t;
@@ -86,12 +120,8 @@ typedef     __uint8_t       __uint_least8_t;
 typedef        __uint16_t      __uint_least16_t;
 typedef        __uint32_t      __uint_least32_t;
 typedef        __uint64_t      __uint_least64_t;
-typedef        __uint64_t      __u_register_t;
-typedef        __uint64_t      __vm_offset_t;
 typedef        __int64_t       __vm_ooffset_t;
-typedef        __uint64_t      __vm_paddr_t;
 typedef        __uint64_t      __vm_pindex_t;
-typedef        __uint64_t      __vm_size_t;
 
 /*
  * Unusual type definitions.